package com.baymax.custom.aspect;

import com.baymax.custom.annation.OpenExecutionTimeStatistics;
import com.baymax.custom.context.StopWatchContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.TreeMap;

/**
 * OpenExecutionTimeStatistics注解切面
 *
 * @author hujiabin wrote in 2024/1/20 16:26
 */
@Aspect
@Component
@Slf4j
public class OpenExecutionTimeStatisticsAspect {

    @Around("@annotation(openExecutionTimeStatistics)")
    public Object openExecutionTimeStatistics(ProceedingJoinPoint joinPoint, OpenExecutionTimeStatistics openExecutionTimeStatistics) throws Throwable {
        try {
            // 如果没有开启，那么开启
            if (!StopWatchContext.isOpenExecutionTimeStatistics()) {
                StopWatchContext.openExecutionTimeStatistics(new TreeMap<>());
            }
            return joinPoint.proceed();
        } finally {
            // 方法执行结束后关闭 耗时统计
            computeExecutionTimeStatistics();
        }
    }

    private void computeExecutionTimeStatistics() {
        // 判断是否有StopWatch
        if (StopWatchContext.hasStopWatch()) {
            // 如果有，那么打印执行情况
            StringBuilder logInfo = new StringBuilder("执行耗时统计：\n");
            for (StopWatch sw : StopWatchContext.getAllStopWatch().values()) {
                logInfo.append(sw.prettyPrint());
                logInfo.append("---------------------------------------------\n");
            }
            logInfo.append("1s = 1,000,000,00 ns");
            log.info(logInfo.toString());
        }
        // 关闭统计
        StopWatchContext.closeExecutionTimeStatistics();
    }
}
